perm filename ADAM.EPF[UP,DOC]1 blob sn#695674 filedate 1983-01-13 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00014 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002				THE ADAM COMPILER
C00006 00003
C00009 00004
C00011 00005	Compiling a source file.
C00014 00006	Switch setting.
C00016 00007	Separate compilation and libraries.
C00020 00008
C00022 00009	Getting started using the compiler.
C00024 00010	Pragmas.
C00026 00011	Differences from standard Ada.
C00033 00012	Miscellaneous notes.
C00034 00013	Implementation notes.
C00038 00014	Predefined environment.
C00040 ENDMK
C⊗;
			THE ADAM COMPILER

			Introduction

The Stanford Adam compiler supports the Adam language, which includes
large subset of the Ada'80.  It may be used as a compiler for a subset
of Ada'80. The subset includes packages, exceptions, generic units and
most tasking constructs; the major omissions involve numerical types.
The compiler is not a validated Ada compiler.


The compiler also supports a simple system for manipulating libraries
for separate compilation. It has a standard set of packages for I/O and
runtime task supervision.
It is intended to run on the DEC TOPS-20
operating system, and also runs on a PDP-10 under the
Stanford AI Lab WAITS operating system. 
It produces PDP-10 assembly language code which will then run with the 
standard runtime packages on TOPS-20 or WAITS.

The purpose of this document is to explain how to use the Adam compiler
and to document the differences between the Ada subset that is compiled
and Ada as defined in the July 1980 manual.

Adam is an experimental language derived from Ada.  It was developed to facilitate
study of issues in Ada implementation. The two primary objectives which
motivated the development of Adam were:  to program
supervisory packages for  multitask scheduling, and
to formulate algorithms for compilation of Ada tasking.

Adam is a subset of the sequential program constructs of Ada
combined with a set of parallel processing constructs
which are lower level than Ada tasking.
In addition,
Adam places strong restrictions on sharing of global objects between processes.
Import declarations and propagate declarations are included.

Algorithms translating Ada tasking into Adam parallel processing
have been developed and implemented (as part of the semantical analysis
phase of the compilation). The translation implements
the procedure call method  of Ada task rendezvous.
Thus the Adam compiler may be used as
an experimental compiler for most of the 1980 Ada language design,
including task types and task rendezvous constructs.

Further description of the Adam language is available in Stanford Computer
Science Report # STAN-CS-81-867. An on-line user's manual for the compiler
is available via Arpanet as <csl.ver.ada>compil.doc @SU-SCORE. The compiler
may be obtained by contacting:

	Edward Falis  or Dr. David Luckham
	Computer Systems Lab
	Stanford University
	Stanford, California  94305

or by sending mail over the net to Falis @SU-SCORE or Luckham @SU-AI.



Instructions below for Score apply for any TOPS-20 site with directory names
appropriately modified.


Compiler commands.

The compiler is invoked by typing:
	r adam	            at SAIL, or
	adam		    at SCORE


On SCORE, if you have no UNIQUE.NAM file in your directory, the compiler will
give you a copy of the one in the system library directory. Be sure to keep
this file in your directory between compilations to ensure compatibility.
Each time the compiler successfully completes its semantic phase, a new version
of this file will be generated. Expunge your directory occasionally to prevent
overflow if you're compiling a lot.

When invoked, the compiler prints a prompt and waits for a command to be typed.

A command to the compiler consists of a command name, or a command name
followed by a list of arguments.  The number and meaning of the arguments
depends on the command name. All commands are terminated by a semicolon.
Arguments are separated by commas.
Commands can be abbreviated to a prefix of the command name.
In what follows, the valid abbreviation of command names is shown in upper case.

After a command has been executed another prompt is printed and another command
can be typed.

A <return> must be typed to terminate a command.

Underscores are represented differently on SAIL and SCORE.
The compiler maps both representations to the same character. So, either can be
used. SAIL underscores print as ↑X at SCORE.

File names which are used as part of a command must not be the same as an Ada
reserved word. The compiler will not recognise logically defined names (eg.
"scr:" for "<scratch>").


When the compiler is initially invoked, all file operations will be 
defaulted to the job's current directory. The defaults for various
kinds of file operations can be changed by the following commands.

	Alias dir-name;    -- will change the default directory for all 
			   -- operations to dir-name.

	Input dir-name;	   -- will change the default directory for source
			   -- program input to dir-name.

	Output dir-name;   -- will change the default directory for any output
			   -- (excluding library modifications) which the
			   -- compiler generates to dir-name.

	Libdir dir-name;   -- will change the default directory for library
		           -- related i/o to dir-name.

dir-name has the form of a TOPS-20 directory name, i.e, <id {.id}> at SCORE
or  p,pn at SAIL.

You must have the appropriate access rights to a directory to read or write on
it. This isn't checked by the compiler. So don't try to write into a directory
which is protected against you.


The command:
	Quit;  terminates the compiler.

The  	Help;  prints a list of the available commands.


Compiling a source file.

Before any source file is compiled a library must be opened. See section on
libraries for how to do this.

To compile a source file, which is in the file, name.ada, the command is:
	Compile name;

This has the following effect. The file is opened and the program is parsed.
If there is a syntax error the compiler returns to the command level.
If there are no syntax errors the static semantic checking is done.
If there are semantic errors, messages will be written to the terminal and also
to a file called name.err.
The compilation units in the source file will be inserted into the open library.
If there are no semantic errors code generation is done.
The compiler generates a file of Fail source code called name.fai.



To run a main program which is in the currently open library, the command is:
	Execute main-program-name;

If no name is given as an argument, MAIN is assumed.

This command tests for completion of the compilation tree
rooted at main-program-name. If it is complete a do file is created
with a command to link the program, and the compiler terminates.
At SAIL the compiler fills the line buffer with a command to run the do file.
A <return> should be typed to run the do file.
At SCORE the name of the do file is displayed. The do file should be run by
typing:

 DO file-name

to the operating system. This loads the program. To run the
program, the TOPS-20 START command should then be typed.


ALL SOURCE FILES MUST END WITH A PERIOD. If a source file doesn't have a period
one can be typed after the compile command.

The command:
	Compile;  will recompile the most recently compiled file from the
		  current compilation session.


Switch setting.

There are various switches which can be set.
Most of the switches are used only for debugging the compiler and should not be
set. The command:
	Set switch;   turns the switch on.
	Reset switch  turns the switch off.

Switch name	Effect when on						    Default

sem		Semantic analysis is done					ON
cg		Code generation is done						ON
seq		Sequential program being compiled				ON
trace		Allows process interactions with the kernel to be traced	OFF
checks		Code is generated to test for some predefined exceptions	OFF
d1		Dumps the abstract syntax tree after parsing			OFF
d2		Dumps the abstract syntax tree after semantics			OFF
		This only works for special cases when the syntax tree 
		contains no recursive pointers.

tsem		Traces the semantic phase of the compiler			OFF
tcg		Traces the code gen phase of the compiler			OFF
bsem		Builtin breaks during semantic phase				OFF
bcg		Builtin breaks during code gen					OFF
nf		All output goes to terminal, no file output			OFF


Separate compilation and libraries.

The compiler supports some of the Ada separate compilation facility.
A library consists of a set of compilation units.
A compilation unit can be a package specification, package body, subprogram
body, or package body subunit.

When a source file name.ada is compiled the interface information for the
units in that file is written to a file called name.ifc.

All library operations during a compilation session are done with respect to
the currently open library. Library file names have the extension .lib.

The main program is designated by having a subprogram body compilation unit
which either has the name MAIN, or has -  pragma MAIN; - in its outermost
declarative part.

If a program consists of several compilation units, the main program should be
the last unit compiled before the program is run.

If the 'separate' facility is used to compile subunits, the parent unit must
be compiled before the separate subunits in order to establish the appropriate
context.

Commands for libraries.

To create a new library the command is:
	CReate name [, password.<pw>];	-- this creates a file name.lib (after
					-- the library is closed) in the
					-- default library directory.
					-- If the optional password specification
					-- is given, then a prompt for <pw> will
					-- will occur at each attempt to open the
					-- library.

To destroy a library the command is:
	DEstroy name;			-- deletes the file name.lib in the
					-- default library directory.

To open an existing library the command is:
	OPen name;			-- looks for name.lib in the default
					-- library directory and opens it if
					-- found.

To close the currently open library the command is:
	CLose;
A quit command will also close any open library.


To copy a library unit from some library to the currently open library
the command is:
	COPY libraryname.unitname;      -- the .lib file extension is omitted
					-- in libraryname.
Example:
	OPen mylib;			-- open an existing library
					-- change the default library directory
					-- to:
at SAIL:
	Libdir lib,ada;
at SCORE:				-- [lib, ada]
	Libdir <csl.ver.ada>		-- <csl.ver.ada>

	COPY io.tty←io;			-- copy a tty i/o module from io.lib
					-- to mylib


To insert new compilation units into a library the procedure is:
open or create the library, and compile the units.

Example:
	CReate foo;
	Compile source;



The following commands can be applied to an open library.
	Dir;	  -- list the table of contents of the library
	Tdir;	  -- list times when units were compiled
	Fdir;	  -- list the files from which units came and were compiled 
		  -- into.
	Wdir;	  -- list the 'with' requirements of the units in the library

	REmove unitname;  -- remove the named unit from the library.

	COmplete unitname; -- tests if the compilation tree rooted at
			   -- unitname has been completely compiled, and
			   -- compiled in the correct order.

A quit command should be given to terminate the compiler to insure that library
files are updated on the disk.


Getting started using the compiler.

   Most likely any simple program will need to do input or output to show
what it is doing. If you want to do terminal i/o there is an Ada package
called TTY←IO which is available. Use this package when there are no tasks
contending for the terminal. If there is contention, use DTTY←IO. To use these
packages, you should first look at the specification part of the source files
which can be found on:

    TTYIOV.ADA[ENV,ADA], DTTYIO.ADA[ENV,ADA]     at SAIL or
    <CSL.VER.ADA>TTYIOV.ADA, <CSL.VER.ADA>DTTYIO.ADA  at SCORE

There should be no need for you to compile these files because you can use
a version  which is already compiled.
To do this you have to copy a library entry from an existing library which
contains it to your library.

The directories [LIB,ADA] at SAIL and <CSL.VER.ADA> at SCORE contain
a library called IO. This library contains copies of TTY←IO and DTTY←IO.
The procedure for doing this copying is described in the section on separate
compilation.

   Once you have a library created (with TTY←IO or DTTY←IO in it if needed)
you can compile an Ada source file. The way to do this is described elsewhere.



Pragmas.

Pragma name	Arguments		Effect

TASK←TRACE	none			Enables tracing of task interactions
					with the runtime kernel. Same effect 
					as the trace switch.

CALL←TRACE	none			When given at the top level of a
					compilation, all procedure calls within
					the file will be traced.

LINE←TRACE	none			When given at the top level of a
					compilation, each statement executed
					within the file will have its line
					number and kind printed out.

CALL←TRACE	list of procedure	Calls to the named procedures will be 
		names			traced.

MEMORY←SIZE	integer			Specifies size of stack for main
					program.

HEAP←SIZE	integer			Specifies size of heap for accessed
					objects.

STACK←HEAP←SIZE	integer			Specifies size of heap for task stacks.

CHECKS		none			Causes code to be generated for checks
					for predefined exceptions. Same effect
					as checks switch.



Differences from standard Ada.

If you have not made use of any of the unimplemented facilities listed
below, then 

		  Ask FALIS @SU-SCORE

Each section contains a list of the main unimplemented features of the July '80
Ada design, and any deviations from the design. <this list is not complete>

2. LEXICAL ELEMENTS

   A. Compilation units must end with a ".". Alternatively, it may be entered 
      directly to the compiler after the source file has been read.

3. DECLARATIONS and TYPES

  A. 	No fixed point types.
  B.	Float does not have accuracy constraints.
  C.	Array objects cannot derive their size from an initial expression.
  D.	No overloading of enumeration literals.
  E.	Discriminant constraints must be static expressions.
  F.	Use Integer constants instead of number declarations (3.2) to avoid
	problems in type resolution.
  G.	When initializing a constrained string constant, or associating an 
	acual parameter with a constrained formal string, no error message
	will result for incompatible lengths; the value associated will be
	of the same length as the constrained object, and either truncated
	or filled (with garbage) to conform.
  H.	Compiler illegally accepts declarations of record objects with variants
	and no discriminant constraint (it appears to default to having all
	variant fields present).

4. NAMES and EXPRESSIONS.

  A.	Aggregates should be qualifed by their type.
  B.	Overload resolution is done in one bottom-up pass. So the type of an
	item in an expression must be determinable independent of its context.
  C.	The "rem" operator is unimplemented. The compiler will accept it in
	the syntax and semantic phases, but will not generate correct code for
	it.

5. STATEMENTS

  A.	Complete record assignment for records which have array fields which
	depend on a discriminant.

6. SUBPROGRAMS

  A.	Actual "out" and "in out" parameters may not be type conversions .
	See 4.6 in ref manual.
  B.	Does not accept explicit subprogram declarations anywhere except in 
	package specifications.
7. PACKAGE
	
  A.	default generic parameters.
  B.	Name parameter associations in generic instantiation.
  C.	Deferred constants of private type.

9. TASKS

  A.	No entry families.
  B.	No Delay alternative in selective wait.
  C.    delay must be given an INTEGER expression instead of DURATION;
	the expression is the number of tenths of seconds to delay.
  D.	No terminate alternative in selective wait.
  E.	Abort statement will not abort dependent tasks.
  F.	No entry'count.
  G.	priorities are 0 .. 10 with 10 being the highest priority.
  H.	No shared variable update.
  I.	If a task created by a library package has not terminated, the program
	will go to sleep rather than terminate when the main program has
	reached	the end of its body and its dependents have terminated.
  J.    Dependency of dynamically allocated task objects is not implemented.
  K.	No timed entry calls.

10. COMPILATION UNITS.

  A.	A task specification and body may not be separated by separate
	compilation units.
	E.g., if a package specification containing a task specification
	is compiled separately from the body of the package containing the task
	body.
	E.g., a subunit cannot be a task body.
  B.	Generic units cannot have subunits.
  C.	Generic bodies must be compiled before any instantiations of the
	generic are done.


11. EXCEPTIONS.

  A.    Propagation of unhandled exceptions from accept body to both partners 
	of the rendezvous. The exception is currently not propagated to the
	task owning the called entry.

  B.    No FAILURE exception.

  C. 	Note: an exception declared in a generic unit refers to a DISTINCT
	exception in each instantiation. This conforms to section 11.1 in the
	July '82 Draft reference manual.

STANDARD.

  A.	No ASCII, SYSTEM packages.
  B.	Control characters are enumeration literals in type CHARACTER.
  

Miscellaneous notes.

There is a limit on the number of tasks which can be activated.
This is determined by the amount of space allocated for task stacks and by the
number of entries in the process table of the runtime kernel.
Currently the kernel has space for 40 tasks (including the main program).
Each task is allocated a stack of size, 1000 + the size of its declarative part.
The amount of total task stack space can be set by the pragma STACK←HEAP←SIZE.
The default value is 40000, which should be sufficient in most cases.


Implementation notes.

   A library file consists of the name of the user who created the library,
the creation date, and a list of compilation units.
For a compilation unit the library keeps a filename pointer to the file which
has the interface information for that unit.

The interface file contains copies of the abstract syntax trees of the visible
parts of the compilation units as follows:

If the unit type is:			The portion of the AST copied is:
-----------------------			-------------------------------------
a package				the package visible part.
a subprogram				the subprogram header.
a generic unit				the entire AST.

   The compiler assigns unique labels to entry points which occur in the
visible part of a compilation unit. Each exception is assigned a unique integer.
To generate these unique names the compiler maintains a file which records the
last values assigned. This file (UNIQUE.NAM) is updated after successful com-
pletion of the semantic checking phase of the compilation. On SCORE, each user
has his own version of this file, which is initialized above the labels and
exceptions occurring in the standard i/o and system environment packages.
On SAIL, a single file is maintained in [lib,ada].	
				
   If the LISP error:

; <space-name> STORAGE-CAPACITY-EXCEEDED
; BKPT GC-OVERFLOW

occurs, you may attempt to increase the allocation for the space using the Lisp
alloc function (see MacLisp Manual). If all else fails, or some other lisp 
error such as

; BKPT GC-LOSSAGE

occurs try typing the following sequence, which will prevent you from losing
any work you've done prior to the current compile:

control-G, 
(parse)
close;

The Lisp environment will print out a lot of junk, but you should be able to
save the state of your library as of before the current compile. Then reset
your Ada fork (at SCORE) and restart the compiler, reopen your library, and
continue by compiling the unit which caused the lisp error.

   If a LISP IO error or DISK error occurs (Score only), chances are you
haven't enough room in your directory to write out a file. If making space 
fails to correct the problem (use the recovery procedure above, and make 
space before calling the compiler again), contact:

FALIS @SU-SCORE.


Predefined environment.

  The compiler assumes the existence of two system interface files.
The first, seqv.ifc, contains modules for the sequential part of the language.
Currently it has:
- access type allocators, called Global←Allocator and Local←Allocator.
- a reclamable boundary tag heap allocator, called Heap←Allocator

The second, parv.ifc, contains modules for the parallel part of the language:
Currently it contains:

- the runtime kernel, called Supervisor
- condition variables, called Conditionvars
- a module supporting the implementation of selective waits.

These files should be on [lib,ada] at SAIL, and on <csl.ver.ada> at SCORE.

On these areas there are also libraries containing I/O modules, and other
modules of general interest.

The source code for these modules is currently on [env,ada] and [pkg,ada] at
SAIL.

Tasking examples may be found on [tsk,ada] at SAIL. Miscellaneous examples may
be found on <csl.ver.examples> at SCORE, [pkg,ada] at SAIL.

There must be a file on [lib,ada] and <csl.ver.ada> called unique.nam for
generating unique labels for entry points and unique integers identifying
user defined exceptions.